package org.deng.vertx.web.dao;

import org.deng.vertx.web.model.AsResult;

import io.netty.util.internal.shaded.org.jctools.queues.MessagePassingQueue.Consumer;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.jdbc.JDBCClient;
import io.vertx.ext.sql.SQLConnection;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.PoolOptions;
import io.vertx.sqlclient.SqlConnection;
import io.vertx.sqlclient.Tuple;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: DengLibin
 * @Date: Create in 2022-04-29 14:28:58
 * @Description: mysql访问
 */
@Slf4j
public class MySqlDao {

    private volatile boolean init = false;

    private MySqlDao() {

    }

    private static class Inner {
        public static final MySqlDao dao = new MySqlDao();

    }

    private MySQLPool client;

    /**
     * @Author: DengLibin
     * @Date: Create in 2022-04-29 17:01:31
     * @Description: 单例对象
     *
     * 
     * @param vertx
     * @return
     */
    public static MySqlDao getInstance() {
        return Inner.dao;

    }

    /**
     * @Author: DengLibin
     * @Date: Create in 2022-04-29 16:55:12
     * @Description: 初始化mysql连接
     *
     * 
     * @param vertx
     */
    public void initMysql(Vertx vertx) {
        synchronized (this) {
            if (this.init) {
                return;
            }
            this.init = true;
        }

        log.info("初始化Mysql客户端");
        // 第一步 配置连接参数
        MySQLConnectOptions connectOptions = new MySQLConnectOptions()
                .setPort(3307)
                .setHost("192.168.56.102")
                .setDatabase("denglibin")
                .setUser("denglibin")
                .setPassword("denglibin");

        // 第二步 配置连接池 Pool options
        PoolOptions poolOptions = new PoolOptions()
                .setMaxSize(5);
        client = MySQLPool.pool(vertx, connectOptions, poolOptions);
        client.getConnection(ar1 -> {
            if (ar1.failed()) {
                log.error("数据库连接失败", ar1.cause());
                return;
            }
            log.info("数据库连接成功");

            // Obtain our connection
            SqlConnection conn = ar1.result();

            // All operations execute on the same connection
            conn.query("select id, usernamee, age, create_date from user")
                    .execute(ar2 -> {
                        // Release the connection to the pool
                        conn.close();

                        if (ar2.succeeded()) {

                            ar2.result().forEach(item -> {

                                log.info("id:{}, name:{}, age:{}, create_date:{}",
                                        item.getLong("id"),
                                        item.getString("username"),
                                        item.getInteger("age"),
                                        item.getLocalDateTime("create_date"));

                            });

                        }
                    });

        });

    }



    public void insert(String sql, Object[] params, Consumer<AsResult<?>> consumer) {
        client.preparedQuery(sql).execute(Tuple.from(params), rs -> {
            if (rs.succeeded()) {
                log.info("添加成功");
                consumer.accept(AsResult.success(null));
            } else {
                rs.cause().printStackTrace();
                consumer.accept(AsResult.fail(rs.cause().getMessage()));
            }
        });
    }

    /**
     * 初始化数据源 使用jdbc
     */
    public void initJDBCDateSource(Vertx vertx) {
        log.info("连接测试:::--------");
        JDBCClient jdbcClient = JDBCClient.createShared(vertx, config());
        jdbcClient.getConnection(conn -> {
            if (conn.failed()) {
                log.info("数据库初始化连接是失败");
                log.error(conn.cause().getMessage());
                return;
            }
            // 获取连接
            final SQLConnection connection = conn.result();
            // 执行 [创建一张test表]
            connection.execute("create table IF NOT  EXISTS test(id int primary key, name varchar(255))", res -> {
                // 如果建表失败
                if (res.failed()) {
                    // 抛出异常[可自定义]
                    throw new RuntimeException(res.cause());
                }
                // 插入一条数据
                connection.execute("insert into test values(1, 'Hello')", insert -> {
                    // 查询数据
                    connection.query("select * from test", rs -> {
                        // 打印结果
                        log.info("数据库初始化成功");
                        for (JsonArray line : rs.result().getResults()) {
                            log.info(line.encode());
                        }
                        // 最后关闭连接
                        connection.close(done -> {
                            // 如果连接释放失败
                            if (done.failed()) {
                                // 抛出异常
                                throw new RuntimeException(done.cause());
                            }
                        });
                    });
                });
            });
        });
    }

    public JsonObject config() {
        return new JsonObject()
                .put("url", "jdbc:mysql://192.168.1.159:3306/denglibin")
                .put("driver_class", "com.mysql.cj.jdbc.Driver")
                .put("user", "root")
                .put("password", "denglibin")
                .put("max_pool_size", 10);
    }

}
